package net.asgarli.abalone.model;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

/**
 * Represents the individual entry in the Unit, such as username, URL, address,
 * etc.
 * 
 * @param <T>
 *            The type of value of entry.
 * 
 * @author Elchin
 */
public class UnitEntry<T> implements Marshallable {
    private static final long serialVersionUID = 1L;

    private String name;

    private T value;

    @Override
    public byte[] writeToBytes() throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeUTF(name);
        oos.writeObject(value);
        oos.close();
        return bos.toByteArray();
    }

    @SuppressWarnings("unchecked")
    @Override
    public void restoreFromBytes(byte[] bytes) throws IOException {
        ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(bytes));
        name = in.readUTF();
        try {
            value = (T) in.readObject();
        } catch (ClassNotFoundException cnfe) {
            throw new IOException(cnfe);
        }
    }

    //
    // ************************* GENERATED *************************
    // ************************* Getters and Setters ***************
    //
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    //
    // ************************* GENERATED *************************
    //
    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("UnitEntry [name=");
        builder.append(name);
        builder.append(", value=");
        builder.append(value);
        builder.append("]");
        return builder.toString();
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((value == null) ? 0 : value.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        @SuppressWarnings("rawtypes")
        UnitEntry other = (UnitEntry) obj;
        if (name == null) {
            if (other.name != null) return false;
        } else if (!name.equals(other.name)) return false;
        if (value == null) {
            if (other.value != null) return false;
        } else if (!value.equals(other.value)) return false;
        return true;
    }
}